import logging
from typing import Iterable

import requests
from django.db.models import QuerySet

from vulnerabilities.improver import Improver
from vulnerabilities.improver import Inference
from vulnerabilities.models import Advisory
from vulnerabilities.models import Alias
from vulnerabilities.models import Kev

logger = logging.getLogger(__name__)


class VulnerabilityKevImprover(Improver):
    """
    Known Exploited Vulnerabilities Improver
    """

    @property
    def interesting_advisories(self) -> QuerySet:
        # TODO Modify KEV improver to iterate over the vulnerabilities alias, not the advisory
        return [Advisory.objects.first()]

    def get_inferences(self, advisory_data) -> Iterable[Inference]:
        """
        Fetch Kev data, iterate over it to find the vulnerability with the specified alias, and create or update
        the Kev instance accordingly.
        """

        kev_url = (
            "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"
        )
        response = requests.get(kev_url)
        kev_data = response.json()
        if response.status_code != 200:
            logger.error(
                f"Failed to fetch the CISA Catalog of Known Exploited Vulnerabilities: {kev_url}"
            )
            return []

        for kev_vul in kev_data.get("vulnerabilities", []):
            alias = Alias.objects.get_or_none(alias=kev_vul["cveID"])
            if not alias:
                continue

            vul = alias.vulnerability

            if not vul:
                continue

            Kev.objects.update_or_create(
                vulnerability=vul,
                defaults={
                    "description": kev_vul["shortDescription"],
                    "date_added": kev_vul["dateAdded"],
                    "required_action": kev_vul["requiredAction"],
                    "due_date": kev_vul["dueDate"],
                    "resources_and_notes": kev_vul["notes"],
                    "known_ransomware_campaign_use": True
                    if kev_vul["knownRansomwareCampaignUse"] == "Known"
                    else False,
                },
            )
        return []
